import Color.*
import java.util.*

/**
 * 主函数
 *
 * fun 代表方法 Function,代表当前时一个方法的修饰
 * main main关键字,代表程序入口,功能和Java的一样
 * args 形参,参数名,与Java中的声明类型相反,参数名在前,类型在后
 * Array<String> String的数组,在kotlin中没有[]这个概念,所有的数组都是array
 * println 是对Java中System.out.println的封装
 * 在kotlin中是不需要写分号的,需要注意一行内,换行相当于分号
 */


fun main(args: Array<String>) {
//    println("hello world")
//    array.add("string")//数组不受影响,可以继续添加内容
//    println(array.toString())
//    a = "asd" //不可赋值其他类型
//    str = "asd" //不可重新赋值
//    println("hello:$name!")
//    println("1+2 = ${1 + 2}")
//    println("a ${if (a >= 10) "大于等于10" else "小于等于10"}")
//
//    val person = Person("lc", false)
//    person.name = "asd"//val声明的属性不可重新赋值
//    person.isMarried = true//相当于setter方法,进行赋值
//    println(person.name)//相当于name的getter方法
//    println(person.isMarried)//相当于getter方法
//    val rectangle = Rectangle(10, 10)
//    rectangle.isSquare  16776960
//    println(getColorStr(BLUE))
//    println(mix(RED, YELLOW))
    play()
}

/**
 * 方法与返回值
 *
 * a = b 就是一个表达式
 * 在kotlin当中,所有的代码都可以是一个表达式
 * :Int代表当前方法的返回值,在kotlin中所有方法都是有返回值的,表面上没有返回的方法其实是有返回值Unit的,相当于Java中void
 * 如果有返回值的方法,可以转换为一个表达式,等号的形式
 * 在kotlin中Int必须与大写字母开头
 */

fun max(a: Int, b: Int): Int = if (a > b) a else b

/***
 * 变量
 *
 * 可变变量和不可变变量(常量)
 * val (value) 不可变变量(常量).在初始化之后不能再次赋值,对应的Java中的final修饰符
 * var (variable) 可变变量.这种变量的值是可以被改变的,对应Java中的普通变量
 * 两种变量的类型可以不写,在Kotlin中可以通过赋值的类型来决定变量的类型
 * 当初始化时类型被固定,再次赋值时,给出的值也必须符合初始化的类型
 * 如果用val声明一个集合,与Java相同,集合内部的内容是可变的
 */

const val str: String = "这是一个String"

val array = arrayListOf("java", "kotlin")

var a = 12

/**
 * 字符串模板
 *
 * 在代码中如果声明一个name,可以加上$符号来进行在String中输出,并且可以添加一些简单的逻辑,在Java中与数据绑定的xml类似
 */
const val name = "lc"

/**
 * 类和属性
 * 包含一个name的getter方法,因为name是final的,所以没有setter方法,只能在构造方法中进行初始化
 * 类后面的括号就相当于这个类的构造方法,可以直接在其中声明变量或者常量
 */


class Person(
    val name: String//只读属性,只可以读取,不可以赋值,在此声明会生成一个name字段和一个getName的方法
    , var isMarried: Boolean//可写属性,生成对应的getter setter方法
)

class Rectangle(private val height: Int, private val width: Int) {
    val isSquare: Boolean
        get() {
            return height == width
        }
}

/**
 * 枚举和when
 * 表示和处理选择
 *
 */
enum class Color(val r: Int, val g: Int, val b: Int) {
    RED(255, 0, 0),
    ORANGE(255, 165, 0),
    YELLOW(255, 255, 0),
    GREEN(0, 255, 255),
    BLUE(0, 0, 255);

    fun rgb() = (r * 256 + g) * 256 + b
}

fun getColorStr(color: Color): String =
    when (color) {
        RED -> "red:${color.rgb()}"
        ORANGE -> "orange:${color.rgb()}"
        YELLOW -> "yellow:${color.rgb()}"
        GREEN -> "green:${color.rgb()}"
        BLUE -> "blue:${color.rgb()}"
    }

fun getColorsStr2(color: Color): String =
    when (color) {
        RED, ORANGE, YELLOW -> "warm"
        GREEN -> "neutral"
        BLUE -> "cold"
    }

fun mix(c1: Color, c2: Color) =
    when (setOf(c1, c2)) {
        setOf(RED, YELLOW) -> "ORANGE"
        setOf(YELLOW, BLUE) -> "GREEN"
        else -> "不知道什么颜色"
    }

//当when没有限定条件的情况下,分支的条件必须为bool类型
fun mix2(c1: Color, c2: Color) =
    when {
        (c1 == RED && c2 == YELLOW) || (c2 == RED && c1 == YELLOW) -> "ORANGE"
        (c1 == YELLOW && c2 == BLUE) || (c2 == YELLOW && c1 == BLUE) -> "GREEN"
        else -> "不知道什么颜色"
    }

//用when来替代if判断
val aa = 1
val bb = 2
var max = if (aa > bb) {
    println(a)
    aa
} else bb

var max2 = when {
    aa > bb -> {
        println(aa)
        aa
    }

    aa == bb -> {
        println(aa + bb)
        aa + bb
    }
    else -> bb
}

/**
 * 循环
 *
 * while循环和do-while循环,和Java完全一致
 * 迭代数字:区间和队列
 * kotlin中有区间的概念,区间的本质是2个值之间的间隔,通常这两个值是数字,一个起始值,一个结束值,中间用..运算符来表示
 * 1..10代表从1到10,并且包含10
 * until代表从1到10,但是不包含10
 *
 * 在kotlin循环中,只有一种形式,for(<item> in <elements>)
 */

val oneToTen = 1..100
val oneToNine = 1 until 10

fun fizzBuzz(i: Int) = when {
    i % 15 == 0 -> "FizzBuzz"
    i % 5 == 0 -> "Buzz"
    i % 3 == 0 -> "Fizz"
    else -> "$i"
}

fun play() {
//    for (i in oneToTen) {
//        println(fizzBuzz(i))
//    }

    //downTo 是倒数的意思,step是步数,也就是98 96.....
//    for (i in 100 downTo 1 step 2){
//
//    }
//    //迭代map
//    val binaryReps = TreeMap<Char, String>()//有序的map集合
//
//    for (c in 'A'..'F') {
//        val binary = Integer.toBinaryString(c.toInt()) //将一个字符转换为二进制
//        binaryReps[c] = binary//根据键C把值存入map
//    }
//
//    for ((key, value) in binaryReps) {//迭代map,声明了2个变量用于保存map中的键值对
//        println("$key=$value")
//    }

//    println(set.javaClass)
//    println(list.javaClass)
//    println(map.javaClass)
    println(strings.last())
    println(numbers.max())
}

//使用in检查集合和区间的成员
fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
fun isNotNum(c: Char) = c !in '0'..'9'

fun recognize(c: Char) = when (c) {
    in '0'..'9' -> "这是一个数字"
    in 'a'..'z', in 'A'..'Z' -> "这是一个字母"
    else -> "可能是中文,也可能是符号"
}

/**
 * 集合
 *
 *
 */

val set = setOf(1, 2, 3)
val list = listOf(1, 2, 3)
val map = mapOf(1 to "one", 2 to "two")
val strings = listOf("first", "second", "fourteenth")
val numbers = setOf(1, 14, 2)



